package com.wyix.service;

import com.wyix.domain.Book;
import com.wyix.repository.BookRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author wangdx
 * @since 2025/8/26
 */
@Service
@RequiredArgsConstructor  // Lombok 自动注入构造函数
public class BookService {
    private final Logger logger = LoggerFactory.getLogger(BookService.class);
    private final BookRepository bookRepository;

    /**
     * 新增图书（事务：确保库存、信息同步）
     */
    @Transactional
    public Book addBook(Book book) {
        logger.info("新增图书：书名={}, ISBN={}", book.getBookName(), book.getIsbn());
        // 业务校验：ISBN 不能重复
        if (bookRepository.findByBookNameLike(book.getIsbn()).size() > 0) {
            throw new RuntimeException("ISBN 已存在：" + book.getIsbn());
        }
        return bookRepository.save(book);
    }

    /**
     * 按 ID 查询图书（二级缓存：标注 @Cacheable，键为图书 ID）
     */
    @Cacheable(value = "bookCache", key = "#id")  // 缓存名称：bookCache，键：id
    public Book getBookById(Long id) {
        logger.info("查询图书 ID={}（首次查询将访问数据库，后续从缓存获取）", id);
        return bookRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("图书不存在：ID=" + id));
    }

    /**
     * 按书名模糊查询
     */
    public List<Book> searchBooksByTitle(String bookName) {
        logger.info("模糊查询图书：书名包含={}", bookName);
        return bookRepository.findByBookNameLike("%" + bookName + "%");
    }

    /**
     * 减少图书库存（借阅时调用，事务确保原子性）
     */
    @Transactional
    public void decreaseStock(Long bookId, Integer count) {
        Book book = getBookById(bookId);
        if (book.getStock() < count) {
            throw new RuntimeException("图书库存不足：书名=" + book.getBookName() + "，当前库存=" + book.getStock());
        }
        book.setStock(book.getStock() - count);
        bookRepository.save(book);
        logger.info("减少图书库存：ID={}，减少数量={}，剩余库存={}", bookId, count, book.getStock());
    }

    /**
     * 趣味功能：查询借阅次数最多的前 10 本书
     */
    @Transactional
    public List<Object[]> getTop10BorrowedBooks() {
        logger.info("查询借阅次数最多的前 10 本书");
        List<Object[]> list = bookRepository.findTop10BorrowedBooks().subList(0, Math.min(10, bookRepository.findTop10BorrowedBooks().size()));
//        Hibernate.initialize(list);
        return list;
    }

}
